package views.games;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

import models.games.ConfrontoRapido;

import org.jdesktop.core.animation.timing.Animator;
import org.jdesktop.core.animation.timing.Interpolator;
import org.jdesktop.core.animation.timing.TimingSource;
import org.jdesktop.core.animation.timing.TimingTarget;
import org.jdesktop.swing.animation.timing.sources.SwingTimerTimingSource;

import views.util.GameColors;
import core.constants.Constants;

public class ConfrontoRapidoView extends GameView implements ActionListener {

	private BufferedImage[] images;
	// private ConfrontoRapido model;
	// private SpeedMatchController controller;
	private Timer cronometro = new Timer(1000, this);
	private int timeMax = Constants.getGameTime();
	private InternalPanel imagePanel;
	private JButton inputYes = new JButton("SI");
	private JButton inputNo = new JButton("NO");
	private JPanel main;
	private JPanel inputPanel;
	private GridBagConstraints gbc;
	private boolean animating;
	private ActionListener currentActionListener;
	private KeyListener currentKeyListener;

	public ConfrontoRapidoView() {
		super(views.util.GameColors.AZZURRO,
				views.util.GameColors.AZZURRO_CHIARO, "TEMPO", "PUNTEGGIO 0",
				"INVIO PER INZIARE");
		// model = new ConfrontoRapido(null);
		// controller = new SpeedMatchController(model, this);
		images = new BufferedImage[ConfrontoRapido.NUMBER_OF_IMAGES];
		initializeImages();
		gbc = new GridBagConstraints();
		main = new JPanel();
		main.setLayout(new GridBagLayout());
		main.setOpaque(false);
		imagePanel = new InternalPanel();
		inputPanel = new JPanel();
		inputPanel.setBackground(GameColors.AZZURRO);
		// inputNo.setEnabled(false);
		inputPanel.add(inputNo);

		inputNo.setFocusable(true);
		inputNo.requestFocus();
		// inputYes.setEnabled(false);
		inputPanel.add(inputYes);
		inputYes.setFocusable(true);
		add(main, BorderLayout.CENTER);
		gbc.gridx = 0;
		gbc.gridy = 0;
		main.add(imagePanel, gbc);
		gbc.insets = new Insets(20, 0, 0, 0);
		gbc.gridx = 0;
		gbc.gridy = 1;
		main.add(inputPanel, gbc);

		// //SetFocus
		// main.setFocusable(true);
		// main.addComponentListener(new ComponentListener() {
		//
		// @Override public void componentShown(ComponentEvent arg0) {
		//
		// System.out.println("shown!");
		// }
		//
		// @Override public void componentResized(ComponentEvent arg0) {
		// main.requestFocus(); System.out.println("Resized"); }
		// @Override public void componentMoved(ComponentEvent arg0) {
		// System.out.println("Moved"); }
		// @Override public void componentHidden(ComponentEvent arg0) {
		// System.out.println("Hidden"); }
		// });

	}

	public void checkFocusMain() {
		// System.out.println("CALL");
		main.requestFocus();
	}

	public void startTimer() {
		cronometro.start();
	}

	public void updateInternalPanel(int initialImageID) {
		imagePanel.setImageId(initialImageID);
	}

	public void addKeyListenerToGame(KeyListener kl) {
		currentKeyListener = kl; // è necessario salvarlo per poterlo rimuovere
		inputYes.addKeyListener(kl);
		inputNo.addKeyListener(kl);
		main.addKeyListener(kl);
	}

	public void addActionListenerToGame(ActionListener al) {
		currentActionListener = al;
		inputYes.addActionListener(al);
		inputNo.addActionListener(al);

	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		timeMax--;
		gameClock.setText("0:" + timeMax);
		if (timeMax == 0) {
			cronometro.stop();
			gameEnded();
		}

	}

	// public void update() {
	//
	// gameClock.setText("Tempo: "+model.getTime());
	//
	//
	// }

	private void initializeImages() {
		String path = "resources/confrontoRapido/";
		String[] imageNames = new String[] { "cardCircle.png",
				"cardEsagono.png", "cardPicche.png", "cardShape.png",
				"cardStar.png", "cardFlower.png" };
		try {
			for (int i = 0; i < images.length; i++) {
				images[i] = ImageIO.read(new File(path + imageNames[i]));
			}
		} catch (IOException e) {
			System.out.println("Path immagine errato.");
			e.printStackTrace();
			System.exit(-1);
		}
	}

	public boolean isAnimating() {
		return animating;
	}

	// public static void main(String[] args) {
	// JFrame f = new JFrame();
	// f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	// f.setSize(800, 680);
	// f.setResizable(false);
	// ConfrontoRapidoView c = new ConfrontoRapidoView();
	// f.add(c);
	// f.addKeyListener(c.controller);
	// f.setVisible(true);
	// }

	@Override
	public void gameEnded() {
		other.setVisible(false);
		gameClock.setVisible(false);
		main.remove(imagePanel);
		main.remove(inputPanel);
		main.removeAll();
		JLabel end = newLabel("Partita Conclusa!", GameColors.AZZURRO_CHIARO);
		gbc.gridx = 1;
		gbc.gridy = 0;
		gbc.gridwidth = 4;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.insets = new Insets(0, 0, 0, 0);
		main.add(end, gbc);
		gbc.gridy = 1;
		main.add(score, gbc);
		JButton restart = newButton("Ricomincia");
		JButton menu = newButton("Menu Giochi");
		gbc.gridy = 2;
		gbc.gridwidth = 2;
		gbc.gridx = 0;
		main.add(restart, gbc);
		gbc.gridx = 2;
		main.add(menu, gbc);
		restart.addActionListener(currentActionListener);
		menu.addActionListener(currentActionListener);
		inputYes.removeKeyListener(currentKeyListener);
		inputNo.removeKeyListener(currentKeyListener);
		main.removeKeyListener(currentKeyListener);
		updateUI();
	}

	private class InternalPanel extends JPanel implements TimingTarget {
		private int imageId;
		private int previousImageId;
		private int xPos;
		private Animator animator;

		// private boolean previousImageIsToDraw = false;

		public InternalPanel() {
			setBackground(GameColors.VERDE);
			Dimension dim = new Dimension(300, 300);
			setPreferredSize(dim);
			TimingSource ts = new SwingTimerTimingSource();
			ts.init();
			Animator.setDefaultTimingSource(ts);
			Interpolator quad = new Interpolator() {

				@Override
				public double interpolate(double fraction) {
					return fraction * fraction;
				}
			};
			animator = new Animator.Builder()
					.setDuration(350, TimeUnit.MILLISECONDS)
					.setInterpolator(quad).addTarget(this).build();
		}

		public void setImageId(int id) {
			previousImageId = imageId;
			imageId = id;
			animator.start();
		}

		@Override
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			BufferedImage currentImage = images[imageId];
			BufferedImage previousImage = images[previousImageId];
			g.drawImage(currentImage, 0, 0, null);
			g.drawImage(previousImage, xPos, 0, null);
		}

		@Override
		public void begin(Animator source) {
			animating = true;
			inputYes.setEnabled(false);
			inputNo.setEnabled(false);
		}

		@Override
		public void end(Animator source) {
			animating = false;
			inputYes.setEnabled(true);
			inputNo.setEnabled(true);
		}

		@Override
		public void repeat(Animator source) {
			// TODO Auto-generated method stub

		}

		@Override
		public void reverse(Animator source) {
			// TODO Auto-generated method stub

		}

		@Override
		public void timingEvent(Animator source, double fraction) {
			xPos = (int) (fraction * 300);
			repaint();
		}
	}

	public void activateButtons() {
		inputNo.setEnabled(true);
		inputYes.setEnabled(true);
	}
}
